<!DOCTYPE html>
<html lang="en">
<head>
  <meta charset="UTF-8">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <title>05_迭代对象-原生可迭代对象</title>
  <!-- 
  在JavaScript中，原生可迭代对象是指那些实现了可迭代协议（iterable protocol）的对象。这些对象可以使用  `for...of`  循环进行迭代，或者使用展开运算符（ `...` ）和其他需要可迭代对象的构造函数（如  `Array.from()` ）进行处理。
  1. Array（数组）：
    - 数组是最常见的可迭代对象，可以使用  `for...of`  循环遍历数组中的每一个元素。
  const arr = [1, 2, 3];
    for (const value of arr) {
        console.log(value); // 输出 1, 2, 3
    }
  2. String（字符串）：
    - 字符串也是可迭代的，每次迭代返回字符串中的一个字符。
  const str = "hello";
    for (const char of str) {
        console.log(char); // 输出 h, e, l, l, o
    }
  3. Map（映射）：
    - Map 对象是一个键值对集合，可以通过  `for...of`  循环遍历其键、值或条目。
  const map = new Map([[1, 'one'], [2, 'two']]);
    for (const [key, value] of map) {
        console.log(key, value); // 输出 1 'one', 2 'two'
    }
  4. Set（集合）：
    - Set 对象是一组唯一值的集合，可以遍历其值。
  const set = new Set([1, 2, 3]);
    for (const value of set) {
        console.log(value); // 输出 1, 2, 3
    }
  5. Arguments 对象：
    -  `arguments`  对象是一个类数组对象，包含传递给函数的参数。虽然它不是一个真正的数组，但可以通过  `Array.from()`  或扩展运算符转换为数组。
  function example() {
        for (const arg of arguments) {
            console.log(arg);
        }
    }
    example(1, 2, 3); // 输出 1, 2, 3
  6. Typed Arrays（类型数组）：
    - 类型数组（如  `Uint8Array` ,  `Float32Array`  等）也是可迭代的。
  const typedArray = new Uint8Array([1, 2, 3]);
    for (const value of typedArray) {
        console.log(value); // 输出 1, 2, 3
    }
  7. NodeList 和 HTMLCollection：
    - 在浏览器环境中， `NodeList`  和  `HTMLCollection`  也可以被视为可迭代对象，通常用于 DOM 操作。
  const nodes = document.querySelectorAll('div');
    for (const node of nodes) {
        console.log(node);
    }
  这些可迭代对象使得在 JavaScript 中处理集合数据变得更加方便和灵活。你可以通过实现自定义的  `@@iterator`  方法来创建自己的可迭代对象。
  -->
</head>
<body>

  <script>
    // 1. 数组
    const arr = [1, 2, 3]
    for (const item of arr) {
      console.log(item)
    }
    const arrIterator = arr[Symbol.iterator]()
    console.log(arrIterator);
    console.log(arrIterator.next());
    console.log(arrIterator.next());
    console.log(arrIterator.next());
    console.log(arrIterator.next());

    // 2. Set
    const set = new Set([1, 2, 3])
    for (const item of set) {
      console.log(item)
    }
    const setIterator = set[Symbol.iterator]()
    console.log(setIterator);
    console.log(setIterator.next());
    console.log(setIterator.next());
    console.log(setIterator.next());
    console.log(setIterator.next());

    // 3. Map
    const map = new Map([['a', 1], ['b', 2], ['c', 3]])
    for (const item of map) {
      console.log(item)
    }
    const mapIterator = map[Symbol.iterator]()
    console.log(mapIterator);
    console.log(mapIterator.next());
    console.log(mapIterator.next());
    console.log(mapIterator.next());
    console.log(mapIterator.next());

    // 4. 字符串
    const str = 'hello'
    for (const item of str) {
      console.log(item)
    }
    const strIterator = str[Symbol.iterator]()
    
    // 5. 函数的 arguments 对象
    function foo() {
      for (const item of arguments) {
        console.log(item)
      }
    }
    foo(1, 2, 3)

    // 6. NodeList
    const pList = document.querySelectorAll('p')
    for (const p of pList) {
      console.log(p)
    }
    

  </script>
  
</body>
</html>